package com.smart.core.starter.exception;

import com.smart.core.starter.model.R;
import com.smart.core.starter.validate.ValidateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
  * 全局异常处理
  * @author guxiaobai
  * @date 2018/11/28 21:28
  */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    /**
     * 处理requestbody参数校验错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = ValidateUtil.toString(bindingResult);
        log.warn("参数验证失败：{}", message);
        return R.error(message);
    }

    /**
     * 处理简单key-value参数校验错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public R handleBindException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = ValidateUtil.toString(bindingResult);
        log.warn("参数验证失败：{}", message);
        return R.error(message);
    }


    /**
     * 处理单个参数校验错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public R handleConstraintViolationException(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        String message = ValidateUtil.toString(violations);
        log.warn("参数验证失败：{}", message);
        return R.error(message);
    }

	/**
	 * 全局异常.
	 *
     * @param e Exception
     * @return R
     */
	@ExceptionHandler(Exception.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R exception(Exception e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        return new R(e);
    }


}
